#include "gtkentryprivate.h"
#include "gtklabel.h"
#include "gtkpango.h"
-#include "gtksearchentryprivate.h"
#include "gtkstylecontextprivate.h"
#include "gtktextprivate.h"
#include "gtkwidgetprivate.h"
if (!entry_set || atk_state_set_contains_state (entry_set, ATK_STATE_DEFUNCT))
{
atk_state_set_add_state (set, ATK_STATE_DEFUNCT);
- g_clear_object (&entry_set);
+ g_clear_object (&entry_set);
return set;
}
}
/* Callbacks */
-
-static void insert_text_cb (GtkEditable *editable,
- gchar *new_text,
- gint new_text_length,
- gint *position);
-static void delete_text_cb (GtkEditable *editable,
- gint start,
- gint end);
-
static gboolean check_for_selection_change (GtkEntryAccessible *entry,
GtkEditable *editable);
G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
-
-static AtkStateSet *
-gtk_entry_accessible_ref_state_set (AtkObject *accessible)
+static GtkText *
+get_text (AtkText *atk_text)
{
- AtkStateSet *state_set;
- gboolean value;
GtkWidget *widget;
- GtkWidget *text;
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
if (widget == NULL)
return NULL;
- text = gtk_widget_get_first_child (widget);
-
- state_set = ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->ref_state_set (accessible);
-
- atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
- if (gtk_widget_has_focus (text))
- atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
-
- g_object_get (G_OBJECT (widget), "editable", &value, NULL);
- if (value)
- atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
- atk_state_set_add_state (state_set, ATK_STATE_SINGLE_LINE);
-
- return state_set;
+ return gtk_entry_get_text_widget (GTK_ENTRY (widget));
}
-static AtkAttributeSet *
-gtk_entry_accessible_get_attributes (AtkObject *accessible)
+static gboolean
+check_for_selection_change (GtkEntryAccessible *accessible,
+ GtkEditable *editable)
{
- GtkWidget *widget;
- AtkAttributeSet *attributes;
- AtkAttribute *placeholder_text;
- char *text = NULL;
+ gboolean ret_val = FALSE;
+ gint start, end;
- attributes = ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->get_attributes (accessible);
+ if (gtk_editable_get_selection_bounds (editable, &start, &end))
+ {
+ if (end != accessible->priv->cursor_position ||
+ start != accessible->priv->selection_bound)
+ /*
+ * This check is here as this function can be called
+ * for notification of selection_bound and current_pos.
+ * The values of current_pos and selection_bound may be the same
+ * for both notifications and we only want to generate one
+ * text_selection_changed signal.
+ */
+ ret_val = TRUE;
+ }
+ else
+ {
+ /* We had a selection */
+ ret_val = (accessible->priv->cursor_position != accessible->priv->selection_bound);
+ }
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- if (widget == NULL)
- return attributes;
+ accessible->priv->cursor_position = end;
+ accessible->priv->selection_bound = start;
- /* Subclasses of GtkEntryAccessible will chain up, so we need to protect
- * the placeholder-text property access
- */
- if (GTK_IS_ENTRY (widget))
- g_object_get (widget, "placeholder-text", &text, NULL);
+ return ret_val;
+}
- if (text == NULL)
- return attributes;
+static void
+insert_text_cb (GtkEditable *editable,
+ gchar *new_text,
+ gint new_text_length,
+ gint *position,
+ GtkEntryAccessible *self)
+{
+ int length;
- placeholder_text = g_malloc (sizeof (AtkAttribute));
- placeholder_text->name = g_strdup ("placeholder-text");
- placeholder_text->value = text;
+ if (new_text_length == 0)
+ return;
- attributes = g_slist_append (attributes, placeholder_text);
+ length = g_utf8_strlen (new_text, new_text_length);
- return attributes;
+ g_signal_emit_by_name (self,
+ "text-changed::insert",
+ *position - length,
+ length);
}
+/* We connect to GtkEditable::delete-text, since it carries
+ * the information we need. But we delay emitting our own
+ * text_changed::delete signal until the entry has update
+ * all its internal state and emits GtkEntry::changed.
+ */
static void
-gtk_entry_accessible_initialize (AtkObject *obj,
- gpointer data)
+delete_text_cb (GtkEditable *editable,
+ gint start,
+ gint end,
+ GtkEntryAccessible *self)
{
- GtkWidget *widget;
- GtkEntryAccessible *gtk_entry_accessible;
- gint start_pos, end_pos;
+ GtkText *textw;
- ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->initialize (obj, data);
+ textw = get_text (ATK_TEXT (self));
+ if (textw == NULL)
+ return;
- gtk_entry_accessible = GTK_ENTRY_ACCESSIBLE (obj);
+ if (end < 0)
+ {
+ gchar *text;
- widget = GTK_WIDGET (data);
- gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), &start_pos, &end_pos);
- gtk_entry_accessible->priv->cursor_position = end_pos;
- gtk_entry_accessible->priv->selection_bound = start_pos;
+ text = gtk_text_get_display_text (textw, 0, -1);
+ end = g_utf8_strlen (text, -1);
+ g_free (text);
+ }
- /* Set up signal callbacks */
- g_signal_connect_after (widget, "insert-text", G_CALLBACK (insert_text_cb), NULL);
- g_signal_connect (widget, "delete-text", G_CALLBACK (delete_text_cb), NULL);
+ if (end == start)
+ return;
+
+ g_signal_emit_by_name (self,
+ "text-changed::delete",
+ start,
+ end - start);
}
static void
-gtk_entry_accessible_notify_gtk (GObject *obj,
- GParamSpec *pspec)
+on_notify (GObject *gobject,
+ GParamSpec *pspec,
+ GtkEntryAccessible *self)
{
GtkWidget *widget;
AtkObject* atk_obj;
- GtkEntryAccessible* entry;
GtkEntryAccessiblePrivate *priv;
- widget = GTK_WIDGET (obj);
+ widget = GTK_WIDGET (gobject);
atk_obj = gtk_widget_get_accessible (widget);
- entry = GTK_ENTRY_ACCESSIBLE (atk_obj);
- priv = entry->priv;
+ priv = gtk_entry_accessible_get_instance_private (self);
if (g_strcmp0 (pspec->name, "cursor-position") == 0)
{
- if (check_for_selection_change (entry, GTK_EDITABLE (widget)))
+ if (check_for_selection_change (self, GTK_EDITABLE (widget)))
g_signal_emit_by_name (atk_obj, "text-selection-changed");
/*
* The entry cursor position has moved so generate the signal.
}
else if (g_strcmp0 (pspec->name, "selection-bound") == 0)
{
- if (check_for_selection_change (entry, GTK_EDITABLE (widget)))
+ if (check_for_selection_change (self, GTK_EDITABLE (widget)))
g_signal_emit_by_name (atk_obj, "text-selection-changed");
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "editable") == 0)
+ else if (g_strcmp0 (pspec->name, "editable") == 0)
{
gboolean value;
- g_object_get (obj, "editable", &value, NULL);
+ g_object_get (gobject, "editable", &value, NULL);
atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE, value);
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "visibility") == 0)
+ else if (g_strcmp0 (pspec->name, "visibility") == 0)
{
gboolean visibility;
AtkRole new_role;
new_role = visibility ? ATK_ROLE_TEXT : ATK_ROLE_PASSWORD_TEXT;
atk_object_set_role (atk_obj, new_role);
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "primary-icon-storage-type") == 0)
+ else if (g_strcmp0 (pspec->name, "primary-icon-storage-type") == 0)
{
- if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY && !priv->icons[GTK_ENTRY_ICON_PRIMARY])
+ if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY &&
+ !priv->icons[GTK_ENTRY_ICON_PRIMARY])
{
- priv->icons[GTK_ENTRY_ICON_PRIMARY] = gtk_entry_icon_accessible_new (entry, GTK_ENTRY_ICON_PRIMARY);
- g_signal_emit_by_name (entry, "children-changed::add", 0,
+ priv->icons[GTK_ENTRY_ICON_PRIMARY] = gtk_entry_icon_accessible_new (self, GTK_ENTRY_ICON_PRIMARY);
+ g_signal_emit_by_name (self, "children-changed::add", 0,
priv->icons[GTK_ENTRY_ICON_PRIMARY], NULL);
}
- else if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_PRIMARY) == GTK_IMAGE_EMPTY && priv->icons[GTK_ENTRY_ICON_PRIMARY])
+ else if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_PRIMARY) == GTK_IMAGE_EMPTY &&
+ priv->icons[GTK_ENTRY_ICON_PRIMARY])
{
gtk_entry_icon_accessible_invalidate (GTK_ENTRY_ICON_ACCESSIBLE (priv->icons[GTK_ENTRY_ICON_PRIMARY]));
- g_signal_emit_by_name (entry, "children-changed::remove", 0,
+ g_signal_emit_by_name (self, "children-changed::remove", 0,
priv->icons[GTK_ENTRY_ICON_PRIMARY], NULL);
g_clear_object (&priv->icons[GTK_ENTRY_ICON_PRIMARY]);
}
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "secondary-icon-storage-type") == 0)
+ else if (g_strcmp0 (pspec->name, "secondary-icon-storage-type") == 0)
{
gint index = (priv->icons[GTK_ENTRY_ICON_PRIMARY] ? 1 : 0);
- if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY && !priv->icons[GTK_ENTRY_ICON_SECONDARY])
+ if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY &&
+ !priv->icons[GTK_ENTRY_ICON_SECONDARY])
{
- priv->icons[GTK_ENTRY_ICON_SECONDARY] = gtk_entry_icon_accessible_new (entry, GTK_ENTRY_ICON_SECONDARY);
- g_signal_emit_by_name (entry, "children-changed::add", index,
+ priv->icons[GTK_ENTRY_ICON_SECONDARY] = gtk_entry_icon_accessible_new (self, GTK_ENTRY_ICON_SECONDARY);
+ g_signal_emit_by_name (self, "children-changed::add", index,
priv->icons[GTK_ENTRY_ICON_SECONDARY], NULL);
}
- else if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY) == GTK_IMAGE_EMPTY && priv->icons[GTK_ENTRY_ICON_SECONDARY])
+ else if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY) == GTK_IMAGE_EMPTY &&
+ priv->icons[GTK_ENTRY_ICON_SECONDARY])
{
gtk_entry_icon_accessible_invalidate (GTK_ENTRY_ICON_ACCESSIBLE (priv->icons[GTK_ENTRY_ICON_SECONDARY]));
- g_signal_emit_by_name (entry, "children-changed::remove", index,
+ g_signal_emit_by_name (self, "children-changed::remove", index,
priv->icons[GTK_ENTRY_ICON_SECONDARY], NULL);
g_clear_object (&priv->icons[GTK_ENTRY_ICON_SECONDARY]);
}
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "primary-icon-name") == 0)
+ else if (g_strcmp0 (pspec->name, "primary-icon-name") == 0)
{
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
{
atk_object_set_name (priv->icons[GTK_ENTRY_ICON_PRIMARY], name);
}
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "secondary-icon-name") == 0)
+ else if (g_strcmp0 (pspec->name, "secondary-icon-name") == 0)
{
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
{
atk_object_set_name (priv->icons[GTK_ENTRY_ICON_SECONDARY], name);
}
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "primary-icon-tooltip-text") == 0)
+ else if (g_strcmp0 (pspec->name, "primary-icon-tooltip-text") == 0)
{
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
{
}
}
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "secondary-icon-tooltip-text") == 0)
+ else if (g_strcmp0 (pspec->name, "secondary-icon-tooltip-text") == 0)
{
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
{
}
}
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "primary-icon-activatable") == 0)
+ else if (g_strcmp0 (pspec->name, "primary-icon-activatable") == 0)
{
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
{
ATK_STATE_ENABLED, on);
}
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "secondary-icon-activatable") == 0)
+ else if (g_strcmp0 (pspec->name, "secondary-icon-activatable") == 0)
{
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
{
ATK_STATE_ENABLED, on);
}
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "primary-icon-sensitive") == 0)
+ else if (g_strcmp0 (pspec->name, "primary-icon-sensitive") == 0)
{
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
{
ATK_STATE_SENSITIVE, on);
}
}
- else if (GTK_IS_ENTRY (widget) &&
- g_strcmp0 (pspec->name, "secondary-icon-sensitive") == 0)
+ else if (g_strcmp0 (pspec->name, "secondary-icon-sensitive") == 0)
{
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
{
ATK_STATE_SENSITIVE, on);
}
}
- else
- GTK_WIDGET_ACCESSIBLE_CLASS (gtk_entry_accessible_parent_class)->notify_gtk (obj, pspec);
+}
+
+static AtkStateSet *
+gtk_entry_accessible_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ gboolean value;
+ GtkWidget *widget;
+ GtkWidget *text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ return NULL;
+
+ text = gtk_widget_get_first_child (widget);
+
+ state_set = ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->ref_state_set (accessible);
+
+ atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
+ if (gtk_widget_has_focus (text))
+ atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
+
+ g_object_get (G_OBJECT (widget), "editable", &value, NULL);
+ if (value)
+ atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
+ atk_state_set_add_state (state_set, ATK_STATE_SINGLE_LINE);
+
+ return state_set;
+}
+
+static AtkAttributeSet *
+gtk_entry_accessible_get_attributes (AtkObject *accessible)
+{
+ GtkWidget *widget;
+ AtkAttributeSet *attributes;
+ AtkAttribute *placeholder_text;
+ char *text = NULL;
+
+ attributes = ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->get_attributes (accessible);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ return attributes;
+
+ g_object_get (widget, "placeholder-text", &text, NULL);
+ if (text == NULL)
+ return attributes;
+
+ placeholder_text = g_malloc (sizeof (AtkAttribute));
+ placeholder_text->name = g_strdup ("placeholder-text");
+ placeholder_text->value = text;
+
+ attributes = g_slist_append (attributes, placeholder_text);
+
+ return attributes;
+}
+
+static void
+gtk_entry_accessible_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkWidget *widget;
+ GtkEntryAccessible *gtk_entry_accessible;
+ gint start_pos, end_pos;
+
+ ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->initialize (obj, data);
+
+ gtk_entry_accessible = GTK_ENTRY_ACCESSIBLE (obj);
+
+ widget = GTK_WIDGET (data);
+ gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), &start_pos, &end_pos);
+ gtk_entry_accessible->priv->cursor_position = end_pos;
+ gtk_entry_accessible->priv->selection_bound = start_pos;
+
+ /* Set up signal callbacks */
+ g_signal_connect_after (widget, "insert-text", G_CALLBACK (insert_text_cb), obj);
+ g_signal_connect (widget, "delete-text", G_CALLBACK (delete_text_cb), obj);
+ g_signal_connect (widget, "notify", G_CALLBACK (on_notify), obj);
}
static gint
if (widget == NULL)
return 0;
- if (GTK_IS_ENTRY (widget))
- {
- if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY)
- count++;
- if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY)
- count++;
- }
+ if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY)
+ count++;
+ if (gtk_entry_get_icon_storage_type (GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY)
+ count++;
return count;
}
if (widget == NULL)
return NULL;
- if (!GTK_IS_ENTRY (widget))
- return NULL;
-
switch (i)
{
case 0:
gtk_entry_accessible_class_init (GtkEntryAccessibleClass *klass)
{
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
class->ref_state_set = gtk_entry_accessible_ref_state_set;
class->get_n_children = gtk_entry_accessible_get_n_children;
class->ref_child = gtk_entry_accessible_ref_child;
- widget_class->notify_gtk = gtk_entry_accessible_notify_gtk;
-
gobject_class->finalize = gtk_entry_accessible_finalize;
}
ATK_OBJECT (entry)->role = ATK_ROLE_TEXT;
}
-static GtkText *
-get_text (AtkText *atk_text)
-{
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
- if (widget == NULL)
- return NULL;
-
- if (GTK_IS_ENTRY (widget))
- return gtk_entry_get_text_widget (GTK_ENTRY (widget));
- else if (GTK_IS_SEARCH_ENTRY (widget))
- return gtk_search_entry_get_text_widget (GTK_SEARCH_ENTRY (widget));
- else
- return NULL; // FIXME;
-}
-
static gchar *
gtk_entry_accessible_get_text (AtkText *atk_text,
gint start_pos,
iface->set_run_attributes = NULL;
}
-static void
-insert_text_cb (GtkEditable *editable,
- gchar *new_text,
- gint new_text_length,
- gint *position)
-{
- GtkEntryAccessible *accessible;
- gint length;
-
- if (new_text_length == 0)
- return;
-
- accessible = GTK_ENTRY_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (editable)));
- length = g_utf8_strlen (new_text, new_text_length);
-
- g_signal_emit_by_name (accessible,
- "text-changed::insert",
- *position - length,
- length);
-}
-
-/* We connect to GtkEditable::delete-text, since it carries
- * the information we need. But we delay emitting our own
- * text_changed::delete signal until the entry has update
- * all its internal state and emits GtkEntry::changed.
- */
-static void
-delete_text_cb (GtkEditable *editable,
- gint start,
- gint end)
-{
- GtkEntryAccessible *accessible;
- GtkText *textw;
-
- accessible = GTK_ENTRY_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (editable)));
-
- textw = get_text (ATK_TEXT (accessible));
- if (textw == NULL)
- return;
-
- if (end < 0)
- {
- gchar *text;
-
- text = gtk_text_get_display_text (textw, 0, -1);
- end = g_utf8_strlen (text, -1);
- g_free (text);
- }
-
- if (end == start)
- return;
-
- g_signal_emit_by_name (accessible,
- "text-changed::delete",
- start,
- end - start);
-}
-
-static gboolean
-check_for_selection_change (GtkEntryAccessible *accessible,
- GtkEditable *editable)
-{
- gboolean ret_val = FALSE;
- gint start, end;
-
- if (gtk_editable_get_selection_bounds (editable, &start, &end))
- {
- if (end != accessible->priv->cursor_position ||
- start != accessible->priv->selection_bound)
- /*
- * This check is here as this function can be called
- * for notification of selection_bound and current_pos.
- * The values of current_pos and selection_bound may be the same
- * for both notifications and we only want to generate one
- * text_selection_changed signal.
- */
- ret_val = TRUE;
- }
- else
- {
- /* We had a selection */
- ret_val = (accessible->priv->cursor_position != accessible->priv->selection_bound);
- }
-
- accessible->priv->cursor_position = end;
- accessible->priv->selection_bound = start;
-
- return ret_val;
-}
-
static gboolean
gtk_entry_accessible_do_action (AtkAction *action,
gint i)